#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os.path
import gtk
import chardet

from scintilla import *
from common.pad_fun import *

def detect_encode(str):
    return chardet.detect(str)['encoding']

class Pad_editor(Scintilla):
    def __init__(self, abs_name = '未命名', text = '', change = False, temp = True):
        Scintilla.__init__(self)

        self.__abs_name     = abs_name
        self.__is_change    = change
        self.__is_temp      = temp
        self.__path, self.__name = os.path.split(self.__abs_name)
        self.__label        = gtk.Label(self.__name)
        #self.editor_info = Editor_info('utf-8')

        self.__indent       = 0

        self.set_init()
        self.set_size_request(0, 0)
        self.SetText(text)
        self.EmptyUndoBuffer()
        self.GrabFocus()
        self.SetFocus(True)

        self.connect('event', self.editor_event)
        self.connect('MarginClick', self.on_margin2_click)
        self.connect('URIDropped', self.on_uri_dorpped)
        self.connect('CharAdded', self.on_char_add)

    def set_init(self):
        self.SetCodePage(65001)
        self.SetMarginTypeN(SC_MARGIN_NUMBER, SC_MARGIN_NUMBER) #显示行号
        self.SetMarginWidthN(SC_MARGIN_NUMBER, 50)              #行号宽度
        self.SetViewWS(SCWS_VISIBLEALWAYS)                      #显示空白
        self.SetTabWidth(4)                                     #Tab宽度
        self.SetUseTabs(False)                                  #是否用Tab or Space
        self.SetTabIndents(True)
        self.SetBackSpaceUnIndents(True)
        self.SetIndentationGuides(SC_IV_LOOKFORWARD)            #缩进线
        self.font_default   = '!文泉驿等宽正黑'
        self.size_defaule   = 10

        self.SetMarginTypeN(SC_MARGIN_BACK, SC_MARGIN_SYMBOL)   #折叠
        self.SetMarginMaskN(SC_MARGIN_BACK, SC_MASK_FOLDERS)
        self.SetMarginWidthN(SC_MARGIN_BACK, 15)
        self.SetProperty("fold", "1")
        self.SetProperty("fold.html", "1")
        self.SetProperty("fold.compact", "1")
        self.SetProperty("fold.comment.python", "1")
        self.MarkerDefine(SC_MARKNUM_FOLDER, SC_MARK_PLUS)
        self.MarkerDefine(SC_MARKNUM_FOLDEROPEN, SC_MARK_PLUS)
        self.MarkerDefine(SC_MARKNUM_FOLDEREND, SC_MARK_EMPTY)
        self.MarkerDefine(SC_MARKNUM_FOLDERMIDTAIL, SC_MARK_EMPTY)
        self.MarkerDefine(SC_MARKNUM_FOLDEROPENMID, SC_MARK_EMPTY)
        self.MarkerDefine(SC_MARKNUM_FOLDERSUB, SC_MARK_EMPTY)
        self.MarkerDefine(SC_MARKNUM_FOLDERTAIL, SC_MARK_EMPTY)
        self.SetFoldFlags(16)
        self.SetModEventMask(SC_MOD_CHANGEFOLD)
        self.SetMarginSensitiveN(2, 1)

        self.SetLexer(SCLEX_PYTHON)                             #Lex
        self.SetStyleBits(5)

        self.set_highlight()

        self.StyleSetFore(STYLE_LINENUMBER, 0x000000)

    def set_highlight(self):
        self.SetKeyWords(0, "and as assert break class continue def del elif else except exec finally for from global if import in is lambda not or pass print raise return self try while with yueld None")
        self.SetKeyWords(1, "")
        self.style_set_spec(STYLE_DEFAULT, 0xeeeeec, 0x000000, self.font_default, self.size_defaule)
        self.SetCaretFore(0xefefef)
        self.StyleClearAll()
        self.style_set_spec(SCE_P_COMMENTLINE, color_tran(0x8a8a8a))
        self.style_set_spec(SCE_P_NUMBER, color_tran(0x729fcf))
        self.style_set_spec(SCE_P_STRING, color_tran(0xef5939))
        self.style_set_spec(SCE_P_CHARACTER, color_tran(0xef5939))
        self.style_set_spec(SCE_P_WORD, (0x4e9a06))
        self.style_set_spec(SCE_P_WORD2, color_tran(0xad7fa8))
        self.style_set_spec(SCE_P_TRIPLE, color_tran(0xef5939))
        self.style_set_spec(SCE_P_TRIPLEDOUBLE, color_tran(0xef5939))
        self.style_set_spec(SCE_P_CLASSNAME, color_tran(0x007BFF), bold = True)
        self.style_set_spec(SCE_P_DEFNAME, color_tran(0x007BFF))

    def style_set_spec(self, style = None, fore=None, back = None, font = None, size = None, bold = None, italic = None):
        """
        设定样式
        @param style:lex样式
        @param fore:前景色
        @param back:背景色
        @param font:字体
        @param size:字体大小
        @param bold:粗提
        @param italic:斜体
        @type style:SCE_P_*-int
        @type fore:hex
        @type back:hex
        @type font:string
        @type size:int
        @type bold:boolen
        @type italic:boolen
        """
        if style != None:
            if back != None:
                self.StyleSetBack(style, back)
            if fore != None:
                self.StyleSetFore(style, fore)
            if font != None:
                self.StyleSetFont(style, font)
            if size != None:
                self.StyleSetSize(style, size)
            if bold != None:
                self.StyleSetBold(style, bold)
            if italic != None:
                self.StyleSetItalic(style, italic)

    #some info
    def get_abs_filename(self):
        """
        获得文件的绝对路径
        @return:文件的绝对路径
        @rtype:string
        """
        return os.path.join(self.__path,self.__name)

    def get_label(self):
        return self.__label

    def is_temp(self):
        """
        是否为临时文件
        @return:是否为临时文件
        @rtype:boolen
        """
        return self.__is_temp

    def set_temp(self, bool):
        self.__is_temp = bool

    def is_change(self):
        """
        是否已修改
        @return:是否已修改
        @rtype:boolen
        """
        return self.__is_change

    def set_change(self, bool):
        self.__is_change = bool

    #event
    def editor_event(self, widget, event):
        if event.type != gtk.gdk.MOTION_NOTIFY:
            if self.CanUndo():
                self.__label.set_text('*'+self.__name)
                self.__is_change = True
            else:
                self.__label.set_text(self.__name)
                self.__is_change = False

    def on_margin2_click(self, editor, modifiers, position, margin):
        line_number = self.LineFromPosition(position)
        if margin == SC_MARGIN_BACK:
            editor.ToggleFold(line_number)
        else:
            pass

    def on_uri_dorpped(self, widget, data):
        self.get_parent().menubar.open_file_creat_new_editor(self.get_parent(), data.rstrip()[7:])

    def on_char_add(self, widget, ch):
        if ch == 10:
            #当换行时 chr(10) = '\n'
            self.automatic_indentation(ch)#自动缩进
        #print self.GetSelectionStart(), self.GetSelectionEnd()

    #fun
    def automatic_indentation(self, ch):
        """
        自动缩进前一行的缩进数
        """
        cur_line        = self.get_current_line()
        front_tab       = self.GetLineIndentation(cur_line-1)
        if self.GetCharAt(self.GetLineEndPosition(cur_line)-2) == 58:
            #为':'时
            self.SetLineIndentation(cur_line, front_tab+self.GetTabWidth())
            for i in range(front_tab+self.GetTabWidth()):
                self.CharRight()
        else:
            self.SetLineIndentation(cur_line, front_tab)
            for i in range(front_tab):
                self.CharRight()

    def get_current_line(self):
        """
        获取当前行号
        @return:当前行号
        @rtype:int
        """
        return self.LineFromPosition(self.GetCurrentPos())